package com.chatplus.application.service.pay.impl.wechat;

import com.chatplus.application.client.pay.WeChatPayClient;
import com.chatplus.application.client.pay.domain.request.wechat.WeChatOrderPayRequest;
import com.chatplus.application.client.pay.domain.request.wechat.WeChatRefundRequest;
import com.chatplus.application.client.pay.domain.response.wechat.TurnRightWxPayRefundV3Result;
import com.chatplus.application.client.pay.domain.response.wechat.WechatOrderPayResponse;
import com.chatplus.application.common.logging.SouthernQuietLogger;
import com.chatplus.application.common.logging.SouthernQuietLoggerFactory;
import com.chatplus.application.common.util.ModelCopyUtils;
import com.chatplus.application.domain.entity.pay.PayRequestEntity;
import com.chatplus.application.domain.entity.pay.RefundRequestEntity;
import com.github.binarywang.wxpay.bean.result.WxPayOrderQueryV3Result;
import com.github.binarywang.wxpay.bean.result.WxPayRefundQueryV3Result;
import com.github.binarywang.wxpay.bean.result.WxPayRefundV3Result;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.google.common.collect.Sets;

import java.util.Set;

/**
 * @author Administrator
 */
public abstract class WeChatPayApiService {

    private static final SouthernQuietLogger LOGGER = SouthernQuietLoggerFactory.getLogger(WeChatPayApiService.class);
    //不可原路退款的状态编码
    public static final Set<String> NON_REFUNDABLE_ERROR_CODES = Sets.newHashSet("TARGET_FAIL");
    public final WeChatPayClient weChatPayClient;

    protected WeChatPayApiService(WeChatPayClient weChatPayClient) {
        this.weChatPayClient = weChatPayClient;
    }
    /**
     * 微信支付抽象方法
     * @return WechatOrderPayResponse
     */
    public abstract WechatOrderPayResponse orderPay(WeChatOrderPayRequest request);

    public WxPayOrderQueryV3Result queryOrderPay(PayRequestEntity payRequestEntity) throws WxPayException {
        return weChatPayClient.queryOrderPay(payRequestEntity);
    }

    public TurnRightWxPayRefundV3Result applyRefund(WeChatRefundRequest request) {
        try {
            WxPayRefundV3Result wxPayRefundV3Result = weChatPayClient.applyRefund(request);
            if (wxPayRefundV3Result != null) {
                return ModelCopyUtils.copy(wxPayRefundV3Result, TurnRightWxPayRefundV3Result.class);
            }
        } catch (WxPayException wxPayException) {
            LOGGER.message("微信支付-申请退款调用失败")
                    .context("request", request)
                    .exception(wxPayException).error();

            String errCode = wxPayException.getErrCode();
            String errCodeDes = wxPayException.getErrCodeDes();
            if (NON_REFUNDABLE_ERROR_CODES.contains(errCode)) {
                TurnRightWxPayRefundV3Result wxPayRefundV3Result = new TurnRightWxPayRefundV3Result();
                wxPayRefundV3Result.setStatus(errCode);
                wxPayRefundV3Result.setErrCodeDes(errCodeDes);
                return wxPayRefundV3Result;
            }
        } catch (Exception e) {
            LOGGER.message("微信支付-申请退款调用失败")
                    .context("request", request)
                    .exception(e).error();
        }
        return null;
    }

    public WxPayRefundQueryV3Result queryRefund(RefundRequestEntity refundRequest) throws WxPayException {
        return weChatPayClient.queryRefund(refundRequest);
    }
}
